package com.ruoyi.system.service.impl;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.domain.PropertyChange;
import com.ruoyi.system.domain.PropertyPicture;
import com.ruoyi.system.enums.ExcelFieldEnum;
import com.ruoyi.system.kiteUtils.CommUtils;
import com.ruoyi.system.mapper.PropertyChangeMapper;
import com.ruoyi.system.mapper.PropertyPictureMapper;
import com.ruoyi.system.service.ISysDictDataService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.system.mapper.PropertyDinaiMapper;
import com.ruoyi.system.domain.PropertyDinai;
import com.ruoyi.system.service.IPropertyDinaiService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.constraints.NotNull;

/**
 * 低耐资产Service业务层处理
 *
 * @author kite
 * @date 2025-03-25
 */
@Service
public class PropertyDinaiServiceImpl implements IPropertyDinaiService {
    @Autowired
    private PropertyDinaiMapper propertyDinaiMapper;

    @Autowired
    private PropertyChangeMapper propertyChangeMapper;

    @Autowired
    private PropertyPictureMapper propertyPictureMapper;

    @Autowired
    private ISysDictDataService iSysDictDataService;

    /**
     * 查询低耐资产
     *
     * @param id 低耐资产主键
     * @return 低耐资产
     */
    @Override
    public PropertyDinai selectPropertyDinaiById(Long id) {
        return propertyDinaiMapper.selectPropertyDinaiById(id);
    }

    @Override
    public boolean checkInstrumentNumberExists(String instrumentNumber) {
        return propertyDinaiMapper.existsByInstrumentNumber(instrumentNumber) > 0;
    }

    /**
     * 查询低耐资产列表
     *
     * @param propertyDinai 低耐资产
     * @return 低耐资产
     */
    @Override
    public List<PropertyDinai> selectPropertyDinaiList(PropertyDinai propertyDinai) {
        List<PropertyDinai> list = propertyDinaiMapper.selectPropertyDinaiList(propertyDinai);

        for (PropertyDinai item : list) {
            PropertyPicture propertyPicture = propertyPictureMapper.selectByNameAndType(item.getLowValueNewProductName(), "2");
            if (propertyPicture != null) {
                item.setPictureUrl(propertyPicture.getPictureUrl());
            }
            item.setChangeSize(propertyChangeMapper.selectCountByNumberAndType(item.getLowValueNewProductNumber(), "低耐资产"));
        }
        return list;
    }

    /**
     * 新增低耐资产
     *
     * @param propertyDinai 低耐资产
     * @return 结果
     */
    @Override
    @Transactional
    public int insertPropertyDinai(PropertyDinai propertyDinai) {
        // 检查家具编号唯一性
        PropertyDinai existing = propertyDinaiMapper.selectPropertyDinaiByNumber(propertyDinai.getLowValueNewProductNumber());
        if (existing != null) {
            throw new ServiceException("低耐品编号 " + propertyDinai.getLowValueNewProductNumber() + " 已存在");
        }
        //校验数据
        checkPropertyDinai(propertyDinai);
        // 设置创建信息
        propertyDinai.setCreateBy(SecurityUtils.getUsername());
        propertyDinai.setCreateTime(new Date());
        int result = propertyDinaiMapper.insertPropertyDinai(propertyDinai);
        if (result <= 0) {
            return result;
        }
        // 3. 记录变更日志
        addPropertyChange4Insert(propertyDinai, "低耐品新增");

        return result;
    }

    /**
     * 修改低耐资产
     *
     * @param propertyDinai 低耐资产
     * @return 结果
     */
    @Override
    @Transactional
    public int updatePropertyDinai(PropertyDinai propertyDinai) {
        //1、查询原始数据
        PropertyDinai originalDinai = propertyDinaiMapper.selectPropertyDinaiById(propertyDinai.getId());
        //2、执行更新操作
        int result = propertyDinaiMapper.updatePropertyDinai(propertyDinai);
        // 3.添加变更流水
        addPropertyChange4Update(originalDinai, propertyDinai, "修改");
        return result;
    }


    /**
     * 批量删除低耐资产
     *
     * @param ids 需要删除的低耐资产主键
     * @return 结果
     */
    @Override
    public int deletePropertyDinaiByIds(Long[] ids) {
        return propertyDinaiMapper.deletePropertyDinaiByIds(ids);
    }

    /**
     * 删除低耐资产信息
     *
     * @param id 低耐资产主键
     * @return 结果
     */
    @Override
    public int deletePropertyDinaiById(Long id) {
        return propertyDinaiMapper.deletePropertyDinaiById(id);
    }

    @Override
    @Transactional
    public void importData(MultipartFile file) {
        List<PropertyDinai> list;
        ExcelUtil<PropertyDinai> excelUtil = new ExcelUtil<>(PropertyDinai.class);
        try {
            list = excelUtil.importExcel(file.getInputStream());
        } catch (Exception e) {
            throw new ServiceException("文件读取失败,请检查文件格式是否正确！");
        }
        StringBuilder errMsg = new StringBuilder();
        for (int i = 0; i < list.size(); i++) {
            PropertyDinai item = list.get(i);
            try {
                PropertyDinai existing = propertyDinaiMapper.selectPropertyDinaiByNumber(item.getLowValueNewProductNumber());
                if (existing != null) {
                    throw new ServiceException("低耐编号 " + item.getLowValueNewProductNumber() + " 已存在");
                }
                //校验数据
                checkPropertyDinai(item);
                // 设置创建信息
                item.setCreateBy(SecurityUtils.getUsername());
                item.setCreateTime(new Date());
                SysUser user = getLoginSysUser();
                item.setRevisedPeople(user.getUserName());//工号
                item.setBackupFields9(user.getNickName());//姓名

                propertyDinaiMapper.insertPropertyDinai(item);
                addPropertyChange4Insert(item, "批量新增");
            } catch (ServiceException e) {
                errMsg.append("第").append(i + 2).append("行错误，").append(e.getMessage()).append("</br>");
            }
        }
        if (StringUtils.isNotBlank(errMsg)) {
            throw new com.ruoyi.common.exception.ServiceException(errMsg.toString());
        }
    }

    @Override
    @Transactional
    public void batchEdit(MultipartFile file) {
        List<PropertyDinai> list;
        ExcelUtil<PropertyDinai> excelUtil = new ExcelUtil<>(PropertyDinai.class);
        try {
            list = excelUtil.importExcel(file.getInputStream());
        } catch (Exception e) {
            throw new ServiceException("文件读取失败,请检查文件格式是否正确！");
        }

        StringBuilder errMsg = new StringBuilder();
        for (int i = 0; i < list.size(); i++) {
            PropertyDinai item = list.get(i);
            try {
                checkPropertyDinai(item);
                // 1. 查询原始数据
                PropertyDinai originalDinai = propertyDinaiMapper.selectPropertyDinaiByNumber(item.getLowValueNewProductNumber());
                if(originalDinai ==null){
                    throw new ServiceException("根据低值品编号，系统未找到该低耐资产");
                }

                item.setId(originalDinai.getId());
                // 2. 执行更新操作
                //永远插入登入人的工号姓名作为变更人信息
                SysUser user = getLoginSysUser();
                item.setRevisedPeople(user.getUserName());//工号
                item.setBackupFields9(user.getNickName());//姓名
                propertyDinaiMapper.updatePropertyDinai(item);

                // 3.添加变更流水
                addPropertyChange4Update(originalDinai, item, "批量修改");
            } catch (ServiceException e) {
                errMsg.append("第").append(i + 2).append("行错误，").append(e.getMessage()).append("</br>");
            }
        }
        if (StringUtils.isNotBlank(errMsg)) {
            throw new com.ruoyi.common.exception.ServiceException(errMsg.toString());
        }
    }

    private void checkPropertyDinai(PropertyDinai obj) {
        if (StringUtils.isBlank(obj.getLowValueNewProductNumber())) {
            throw new ServiceException("【低值品编号】不能为空");
        }
        if (StringUtils.isBlank(obj.getLowValueNewProductName())) {
            throw new ServiceException("【低值品名称】不能为空");
        }
        if (StringUtils.isBlank(obj.getInstrumentNumber())) {
            throw new ServiceException("【资产编号】不能为空");
        }
        if (StringUtils.isBlank(obj.getRevisedReason())) {
            throw new ServiceException("【修订事由】不能为空");
        }
//        try {
//            CommUtils.findUserCode(obj.getRevisedPeople());
//        } catch (ServiceException e) {
//            throw new ServiceException("【最新修订人】的user_code未找到，请重新检查或联系管理员");
//        }
        try {
            CommUtils.findUserCode(obj.getUsers());
        } catch (ServiceException e) {
            throw new ServiceException("【使用人】的user_code未找到，请重新检查或联系管理员");
        }
        try {
            CommUtils.findUserCode(obj.getKeeper());
        } catch (ServiceException e) {
            throw new ServiceException("【保管人】的user_code未找到，请重新检查或联系管理员");
        }
        try {
            CommUtils.findUserCode(obj.getResponser());
        } catch (ServiceException e) {
            throw new ServiceException("【责任人】的user_code未找到，请重新检查或联系管理员");
        }
//        try {
//            CommUtils.findUserCode(obj.getResponserHistory());
//        } catch (ServiceException e) {
//            throw new ServiceException("【历史责任人】的user_code未找到，请重新检查或联系管理员");
//        }
    }

    private void addPropertyChange4Insert(PropertyDinai propertyDinai, String type) {
        PropertyChange changeLog = new PropertyChange();
        changeLog.setInstrumentNumber(propertyDinai.getLowValueNewProductNumber()); //编号
        changeLog.setBackupFields1(propertyDinai.getLowValueNewProductName());//名称
        // 变更情况改为动态生成
        StringBuilder changeDetail = new StringBuilder("【新增低耐资产】");
        List<Map<ExcelFieldEnum, String>> excelFields = CommUtils.getExcelFields(propertyDinai);
        for (Map<ExcelFieldEnum, String> map : excelFields) {
            String value = map.get(ExcelFieldEnum.FILED_VALUE);
            String excelAnnotationName = map.get(ExcelFieldEnum.EXCEL_ANNOTATION_NAME);
            if (StringUtils.isNotBlank(value)) {
                changeDetail.append(excelAnnotationName).append("：").append(value).append("；");
            }
        }
        changeLog.setChangeSituationStatus(changeDetail.toString()); //变更情况
        // 操作人信息
        String revisedPeople = propertyDinai.getRevisedPeople();
        revisedPeople = StringUtils.isNotBlank(revisedPeople) ? revisedPeople : SecurityUtils.getUsername();
        changeLog.setChangeSituationPerson(revisedPeople);//变更人
        // 时间信息
        String revisedTm = propertyDinai.getRevisedTm();
        revisedTm = StringUtils.isNotBlank(revisedTm) ? revisedTm : new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
        changeLog.setChangeSituationTm(revisedTm); //变更时间
        // 变更事由
        String revisedReason = propertyDinai.getRevisedReason();
        changeLog.setChangeSituationResason(StringUtils.isNotBlank(revisedReason) ? revisedReason : "初始入库"); //变更事由
        // 操作类型标记
        changeLog.setBackupFields2(type); //变更类型
        changeLog.setBackupFields3("低耐资产");
        changeLog.setBackupFields4(propertyDinai.getStorageLocation());//存放地
        changeLog.setBackupFields5(propertyDinai.getKeeper());//保管人
        changeLog.setBackupFields6(propertyDinai.getUsers());//使用人
        changeLog.setBackupFields7(propertyDinai.getResponser());//责任人
        changeLog.setBackupFields8(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        changeLog.setBackupFields9(propertyDinai.getBackupFields9());
        propertyChangeMapper.insertPropertyChange(changeLog);
    }

    private void addPropertyChange4Update(PropertyDinai originalDinai, PropertyDinai newDinai, String updateType) {
        PropertyChange changeLog = new PropertyChange();
        changeLog.setInstrumentNumber(newDinai.getLowValueNewProductNumber()); //编号
        changeLog.setBackupFields1(newDinai.getLowValueNewProductName());//名称
        StringBuilder changeDetail = new StringBuilder("【修改低耐资产】，");
        List<Map<ExcelFieldEnum, String>> oldExcelFields = CommUtils.getExcelFields(originalDinai);
        List<Map<ExcelFieldEnum, String>> newExcelFields = CommUtils.getExcelFields(newDinai);
        int changeSize = 0;
        for (int i = 0; i < oldExcelFields.size(); i++) {
            String oldFileValue = oldExcelFields.get(i).get(ExcelFieldEnum.FILED_VALUE);
            String newFileValue = newExcelFields.get(i).get(ExcelFieldEnum.FILED_VALUE);
            if (StringUtils.isNotBlank(oldFileValue) || StringUtils.isNotBlank(newFileValue)) {
                if (!StringUtils.equals(oldFileValue, newFileValue)) {
                    changeDetail.append(oldExcelFields.get(i).get(ExcelFieldEnum.EXCEL_ANNOTATION_NAME))
                            .append("从“").append(oldFileValue).append("”修改为“").append(newFileValue).append("”；");
                    changeSize++;
                }

            }
        }
        if (changeSize == 0) {
            throw new ServiceException("数据未修改，无法变更");
        }
        changeLog.setChangeSituationStatus(changeDetail.toString()); //变更情况

        // 操作人信息
        String revisedPeople = newDinai.getRevisedPeople();
        revisedPeople = StringUtils.isNotBlank(revisedPeople) ? revisedPeople : SecurityUtils.getUsername();
        changeLog.setChangeSituationPerson(revisedPeople);//变更人

        // 时间信息
        String revisedTm = newDinai.getRevisedTm();
        revisedTm = StringUtils.isNotBlank(revisedTm) ? revisedTm : new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
        changeLog.setChangeSituationTm(revisedTm); //变更时间

        // 变更事由
        String revisedReason = newDinai.getRevisedReason();
        changeLog.setChangeSituationResason(StringUtils.isNotBlank(revisedReason) ? revisedReason : ""); //变更事由

        // 操作类型标记
        changeLog.setBackupFields2(updateType); //变更类型
        changeLog.setBackupFields3("低耐资产");
        changeLog.setBackupFields4(newDinai.getStorageLocation());//存放地
        changeLog.setBackupFields5(newDinai.getKeeper());//保管人
        changeLog.setBackupFields6(newDinai.getUsers());//使用人
        changeLog.setBackupFields7(newDinai.getResponser());//责任人
        changeLog.setBackupFields8(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        changeLog.setBackupFields9(newDinai.getBackupFields9());
        propertyChangeMapper.insertPropertyChange(changeLog);
    }
    @NotNull
    private SysUser getLoginSysUser() {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        if (loginUser == null) {
            throw new RuntimeException("请先登录");
        }
        SysUser user = loginUser.getUser();
        if (user == null) {
            throw new RuntimeException("当前用户信息为空");
        }
        return user;
    }
}

